//
// Created by alexa on 5/13/2024.
//

#include "BattalionRepository.h"

#include <fstream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

Battalion *BattalionRepository::findById(string id) {
    return source.getById(id);
}

void BattalionRepository::save(Battalion *battalion) {
    if (!source.getById(battalion->getId())) source.add(battalion);

    if (!fileSourcePath.empty()) {
        saveDataToFile();
    }
}

void BattalionRepository::deleteOne(Battalion *battalion) {
    if (source.getById(battalion->getId())) {
        source.removeById(battalion->getId());
    }
    if (!fileSourcePath.empty()) {
        saveDataToFile();
    }
}

vector<Battalion *> BattalionRepository::findAll() {
    return source.getAll();
}

BattalionRepository::BattalionRepository(const string &fileSourcePath) : fileSourcePath(fileSourcePath) {
    if (!fileSourcePath.empty()) {
        loadDataFromFile();
    }
}

void BattalionRepository::loadDataFromFile() {
    if (fileSourcePath.empty()) return;
    ifstream file(fileSourcePath);
    if (!file.good()) {
        file.close();
        return;
    }
    json data;
    try {
        data = json::parse(file);
    } catch (json::exception &pass) {
        file.close();
        return;
    }
    if (!data.is_array()) return;
    for (const auto &el: data) {
        try {
            string id = el.at("id");
            string name = el.at("name");
            vector<string> unitsIds = el.at("unitsIds");
            Battalion *battalion = new Battalion(name);
            battalion->setId(id);
            for (const auto &unitId: unitsIds) {
                battalion->addUnitId(unitId);
            }
            this->source.add(battalion);
        } catch (json::exception &e) {
            continue;
        }
    }
    file.close();
}

void BattalionRepository::saveDataToFile() {
    ofstream file(fileSourcePath);

    json jarr = json::array();

    vector<Battalion *> list = findAll();

    for (const auto &el: list) {
        json jobj = json::object();
        jobj["id"] = el->getId();
        jobj["name"] = el->getName();
        jobj["unitsIds"] = el->getAllUnitsIds();
        jarr.push_back(jobj);
    }
    file << jarr.dump(4) << endl;
    file.close();
}

const string &BattalionRepository::getFileSourcePath() const {
    return fileSourcePath;
}

void BattalionRepository::setFileSourcePath(const string &fileSourcePath) {
    this->fileSourcePath = fileSourcePath;
    if (!fileSourcePath.empty()) {
        loadDataFromFile();
    }
}

BattalionRepository::~BattalionRepository() {
    vector<Battalion *> list = findAll();
    for (auto &el: list) {
        delete el;
    }
}



